import java.util.ArrayList;
import java.util.Scanner;
/**
 * 实验题目四： 模拟请求分页管理中地址转换和缺页中断处理
 */
//定义一个page类
class page {
    private int pages;  //页号
    private int existFlag;  //存在标志
    private int mainNum;//主存块号
    private int modifyFlag;  //修改标志
    private int diskNum;//在磁盘上块号

    public page() {

    }
    public page(int pages, int existFlag, int mainNum, int modifyFlag, int diskNum) {
        this.pages = pages;
        this.existFlag = existFlag;
        this.mainNum = mainNum;
        this.modifyFlag = modifyFlag;
        this.diskNum = diskNum;
    }

    @Override
    public String toString() {
        return "page{" +
                "pages=" + pages +
                ", existFlag=" + existFlag +
                ", mainNum=" + mainNum +
                ", modifyFlag=" + modifyFlag +
                ", diskNum=" + diskNum +
                '}';
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public int getexistFlag() {
        return existFlag;
    }

    public void setexistFlag(int existFlag) {
        this.existFlag = existFlag;
    }

    public int getmainNum() {
        return mainNum;
    }

    public void setmainNum(int mainNum) {
        this.mainNum = mainNum;
    }

    public int getmodifyFlag() {
        return modifyFlag;
    }

    public void setmodifyFlag(int modifyFlag) {
        this.modifyFlag = modifyFlag;
    }

    public int getdiskNum() {
        return diskNum;
    }

    public void setdiskNum(int diskNum) {
        this.diskNum = diskNum;
    }
}

public class Main {
    static ArrayList<page> arr = new ArrayList<page>();              //磁盘链表
    static ArrayList<page> page = new ArrayList<page>(3);//主存链表



    //菜单显示
    private static void menu() {
        while (true) {
            System.out.println("*模拟请求分页管理中地址转换和缺页中断处理*");
            System.out.println("*             功能菜单          *");
            System.out.println("*             请选择：          *");
            System.out.println("*             1.地址转换        *");
            System.out.println("*             2.查看页表        *");
            System.out.println("*             0.退出           *");
            System.out.println("*******************************");
            System.out.print("请选择指令:");
            Scanner scanner = new Scanner(System.in);
            int n = scanner.nextInt();
            switch (n){
                case 1:
                    System.out.println("地址转换");
                    change();
                    break;
                case 2:
                    System.out.println("查看页表");
                    show();
                    break;
                case 0:
                    System.exit(0);
                    break;
                default:
                    System.out.println("请重新选择!");

            }
        }
    }
    //页表显示
    private static void show() {

        System.out.println("*****************************************");
        System.out.println("页号   存在标志   主存块号   修改标志  在磁盘上块号");
        for (int i = 0; i < page.size(); i++){
            page temp = page.get(i);
            System.out.println( temp.getPages() + "\t\t  " + temp.getexistFlag() + "\t\t" + temp.getmainNum()+ "\t\t\t" + temp.getmodifyFlag()+ "\t\t\t"+" " + temp.getdiskNum());
        }
        System.out.println("*****************************************");
    }
    //地址转换
    private static void change() {
        Scanner sc = new Scanner(System.in);

        int pd = 0;
        System.out.println("请输入逻辑地址：");
        int x = Integer.parseInt(sc.nextLine());
        int p = x / 1024;  //页数
        int yn = x % 1024; //页内地址
        if (x == 0) {
            //显示主存链表
            for (int i = 0; i < page.size(); i++) {
                System.out.println(page.get(i));
            }
        }
        else if (x > 0 && x <= 7 * 1024 - 1) {
            for (int i = 0; i < page.size(); i++) {
                if (page.get(i).getPages() == p) {
                    page.get(i).setmodifyFlag(1);
                    pd++;
                    break;
                }
            }
            if (pd == 0) {
                interrupt(p);
            }
            System.out.println("所在页号：" + p);
            System.out.println("页内地址：" + yn);
        }
    }
    //缺页中断
    public static void interrupt(int p) {
        int y = 0;                  //主存块号
        page.get(0).setexistFlag(0);      //首个页存在时间最长，将新的页与之进行替换
        y = page.get(0).getmainNum(); //得到主存块号
        page.get(0).setmainNum(0);    //主存块号置0
        arr.add(page.get(0));         //添加进页表arr
        page.remove(0);         //从主存中移除

        for (int i = 0; i < arr.size(); i++) {
            if (arr.get(i).getPages() == p) {
                arr.get(i).setexistFlag(1);
                arr.get(i).setmainNum(y);   //主存块号
                arr.get(i).setmodifyFlag(1);    //新添加页，将修改位改为1
                page.add(arr.get(i));
                arr.remove(i);
                break;
            }
        }
    }
    //主函数
    public static void main(String[] args) {
        // pages 页号
        // existFlag 存在标志
        // mainNum 主存块号
        // modifyFlag 修改标志
        // diskNum 在磁盘上块号
        //初始化页表信息
        page page0 = new page(0, 1, 1, 0, 1);
        page page1 = new page(1, 1, 2, 0, 2);
        page page2 = new page(2, 1, 3, 0, 3);
        page page3 = new page(3, 0, 0, 0, 4);
        page page4 = new page(4, 0, 0, 0, 5);
        page page5 = new page(5, 0, 0, 0, 6);
        page page6 = new page(6, 0, 0, 0, 7);
        page page7 = new page(7, 0, 0, 0, 8);

        page.add(page0);
        page.add(page1);
        page.add(page2);
        arr.add(page3);
        arr.add(page4);
        arr.add(page5);
        arr.add(page6);
        arr.add(page7);
        menu();

    }
}

